#include <stdio.h>

#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#endif

#include <stdlib.h>
#include <math.h>
#define ESCAPE 27

int window;

typedef struct
{
	float x,y;
}Punto;

typedef struct
{
	float r,g,b;
}Color;

void InitGL (int windowWidth, int windowHeight, int windowDepth, const char * windowTitle)
{
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
	glutInitWindowSize(windowWidth,windowHeight);
	window = glutCreateWindow(windowTitle);


	// Codigo de los shaders
    GLchar vertexShaderText[]=
		"varying vec3 col;										"
        "void main()                               				 	"
        "{                                          				"
        "        gl_Position = vec4(gl_Vertex.xy,0.0,1.0);        	"
		"		 col = gl_Color.rgb;								"
        "}                                          				";

    GLchar fragmentShaderText [] = 
		"varying vec3 col;							"
        "void main()								"
        "{											"
        "   gl_FragColor = vec4(col,1.0);			"
		"}											";

	const GLchar * vt = vertexShaderText;
	const GLchar * ft = fragmentShaderText;

	// Creamos 2 shaders en OpenGL
	GLuint vshader = glCreateShader(GL_VERTEX_SHADER);
	GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER);

	// Cargamos el codigo de los shaders
    glShaderSource(vshader,1,&vt,NULL);
    glShaderSource(fshader,1,&ft,NULL);

	// Los compilamos 
	glCompileShader(vshader);
	glCompileShader(fshader);

	// Creamos el shader program y unimos los shaders
	GLuint program = glCreateProgram();
	glAttachShader(program, vshader);
	glAttachShader(program, fshader);

	// Enlazamos el programa
	glLinkProgram(program);

	// Indicamos que queremos usar este shader
	glUseProgram(program);
}

/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y) 
{
	if (key == ESCAPE) 
	{ 
		glutDestroyWindow(window); 
	    exit(1);
    }
}

void DrawGLScene()
{	
	// Limpiamos la imagen con color blanco
	glClearColor(1.0,1.0,1.0,1.0);
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

	// Coordenadas de los puntos del objeto
	const Punto vertexPos[3] = { {-0.25,-0.15}, {0.25,-0.15}, {0,0.35} };
	const Color vertexColor[9] = { {0.0,0.0,1.0}, {0.0,1.0,0.0}, {1.0,0.0,0.0} };

	// Posicion de los objetos
	const Punto modelspos[5] = { {0,0}, {0.4,0.4}, {-0.4,-0.4}, {0.4,-0.4}, {-0.4,0.4} };

	float newVertexPos[3*2];

	// Activamos el render de vertex arrays
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
	glColorPointer(3,GL_FLOAT,0,vertexColor);
	glVertexPointer(2,GL_FLOAT,0,newVertexPos);
	// Indicamos de donde debe tomar los datos

	for(int i=0;i<5;++i)
	{
		for(int j=0;j<3;++j)
		{
			newVertexPos[j*2] = vertexPos[j].x + modelspos[i].x;
			newVertexPos[j*2+1] = vertexPos[j].y + modelspos[i].y;
		}
		// Dibujamos el triangulo
		glDrawArrays(GL_TRIANGLES,0, 3);
	}
	// Mostramos el triangulo en pantalla 
	glutSwapBuffers();
}

void ReSizeGLScene(int width, int height)
{
	glViewport(0, 0, width, height);		
}

int main(int argc, char ** argv) 
{
	glutInit(&argc, argv);  
	InitGL(800,600,24,"OpenGL Tutorial1");
	glutDisplayFunc(&DrawGLScene);  

	glutIdleFunc(&DrawGLScene);
	glutReshapeFunc(&ReSizeGLScene);
	glutKeyboardFunc(&keyPressed);

	glutMainLoop();  
	return 1;
}

